// bigNumber.ts
import { BigNumber } from "bignumber.js";

const BN = BigNumber.clone();

// 定义数值类型，支持字符串、数字、BigNumber对象，以及undefined和null
type NumericValue = string | number | BigNumber | undefined | null;

/**
 * 检查是否需要跳过计算
 * @param x 第一个值
 * @param y 第二个值
 * @returns 返回布尔值表示是否需要跳过计算
 */
function calculated(x: NumericValue, y: NumericValue): boolean {
  return (!x && x !== 0) || (!y && y !== 0);
}

/**
 * 乘法运算
 * @param x 第一个因数
 * @param y 第二个因数
 * @param isToFixed 是否返回保留2位小数的结果
 * @returns 返回乘积的字符串表示，如果输入无效则返回undefined
 */
function multipliedBy(
  x: NumericValue,
  y: NumericValue,
  isToFixed: boolean = false
): string | undefined {
  if (calculated(x, y)) return undefined;

  // 处理可能的undefined/null值，转换为0进行计算
  const safeX = x ?? 0;
  const safeY = y ?? 0;
  const result = BN(safeX).multipliedBy(BN(safeY));
  return isToFixed ? result.toFixed(2) : result.toString();
}

/**
 * 除法运算
 * @param x 被除数
 * @param y 除数（不能为0）
 * @param isToFixed 是否返回保留2位小数的结果
 * @returns 返回商的字符串表示，如果输入无效则返回undefined
 */
function dividedBy(
  x: NumericValue,
  y: NumericValue,
  isToFixed: boolean = false
): string | undefined {
  if (calculated(x, y) || y === 0 || y === "0") return undefined;

  // 处理可能的undefined/null值，转换为0进行计算
  const safeX = x ?? 0;
  const safeY = y ?? 0;
  const result = BN(safeX).dividedBy(BN(safeY));
  return isToFixed ? result.toFixed(2) : result.toString();
}

/**
 * 减法运算
 * @param x 被减数
 * @param y 减数
 * @param isToFixed 是否返回保留2位小数的结果
 * @returns 返回差的字符串表示，如果输入无效则返回undefined
 */
function minus(x: NumericValue, y: NumericValue, isToFixed: boolean = false): string | undefined {
  if (calculated(x, y)) return undefined;

  // 处理可能的undefined/null值，转换为0进行计算
  const safeX = x ?? 0;
  const safeY = y ?? 0;
  const result = BN(safeX).minus(BN(safeY));
  return isToFixed ? result.toFixed(2) : result.toString();
}

/**
 * 加法运算
 * @param x 第一个加数
 * @param y 第二个加数
 * @param isToFixed 是否返回保留2位小数的结果
 * @returns 返回和的字符串表示，如果输入无效则返回undefined
 */
function plus(x: NumericValue, y: NumericValue, isToFixed: boolean = false): string | undefined {
  if (calculated(x, y)) return undefined;

  // 处理可能的undefined/null值，转换为0进行计算
  const safeX = x ?? 0;
  const safeY = y ?? 0;
  const result = BN(safeX).plus(BN(safeY));
  return isToFixed ? result.toFixed(2) : result.toString();
}

/**
 * 比较大小
 * @param x 第一个比较值
 * @param y 第二个比较值
 * @returns 返回x是否小于y的布尔值，如果输入无效则返回undefined
 */
function isLessThan(x: NumericValue, y: NumericValue): boolean | undefined {
  if (calculated(x, y)) return undefined;

  // 处理可能的undefined/null值，转换为0进行比较
  const safeX = x ?? 0;
  const safeY = y ?? 0;
  return BN(safeX).isLessThan(BN(safeY));
}

export { multipliedBy, dividedBy, minus, plus, BN, isLessThan };
export type { NumericValue };
